/**
 * 
 */
package org.stars.daostars.core;


import java.io.Serializable;
import java.util.ArrayList;
import java.util.Map;

import org.stars.daostars.ParameterConverter;
import org.stars.daostars.SQLExceptionTranslator;
import org.stars.daostars.exceptions.translators.DefaultSQLExceptionTranslatorImpl;
import org.stars.daostars.sqlmapper.SqlMapper;
import org.stars.database.ConnectionPoolManager;
import org.stars.datastructure.map.CaseInsensitiveHashMap;
import org.stars.util.StringUtility;
import org.stars.util.diagnostic.DefaultStackTraceDiagnosticHandler;
import org.stars.util.diagnostic.StackTraceDiagnosticHandler;

/**
 * Rappresenta un profilo di daostar. Un profilo tipicamente rappresenta
 * l'insieme di definizioni di dao per un determinato tipo di database.
 * 
 * @author Francesco Benincasa (908099)
 * @date 06/nov/07, 20:43:52
 * 
 */
public class Profile implements Serializable {

	/**
	 * traduttore di eccezioni.
	 */
	protected SQLExceptionTranslator sQLExceptionTranslator;
	
	/**
	 * @return the exceptionTranslator
	 */
	public SQLExceptionTranslator getSQLExceptionTranslator() {
		return sQLExceptionTranslator;
	}

	/**
	 * @param exceptionTranslator the exceptionTranslator to set
	 */
	public void setSQLExceptionTranslator(SQLExceptionTranslator exceptionTranslator) {
		this.sQLExceptionTranslator = exceptionTranslator;
	}

	/**
	 * convertitore dei parametri.
	 */
	private ParameterConverter parameterConverter;
	
	/**
	 * @return the stackTraceDiagnosticHandler
	 */
	public StackTraceDiagnosticHandler getStackTraceDiagnosticHandler() {
		return stackTraceDiagnosticHandler;
	}

	/**
	 * @param stackTraceDiagnosticHandler
	 *            the stackTraceDiagnosticHandler to set
	 */
	public void setStackTraceDiagnosticHandler(
			StackTraceDiagnosticHandler stackTraceDiagnosticHandler) {
		this.stackTraceDiagnosticHandler = stackTraceDiagnosticHandler;
	}
	
	/**
	 * gestore del display dello stack durante l'elaborazione delle query
	 */
	private StackTraceDiagnosticHandler stackTraceDiagnosticHandler;
	
	/**
	 * serial id
	 */
	private static final long serialVersionUID = -7939743552047757830L;

	/**
	 * Aggiunge una sorgente
	 * 
	 * @param source
	 * @return <code>true</code>
	 */
	public boolean addSource(Source source) {
		daoSource.add(source);
		return true;
	}

	/**
	 * Aggiunge un namespace. Nel caso esso già esista, provvede a
	 * sovrascriverlo.
	 * 
	 * @param namespace
	 *            namespace da aggiungere.
	 * @return <code>true</code>
	 */
	public boolean addNamespace(Namespace namespace) {
		String nameNS = namespace.getName().toUpperCase();
		daoNamespaceSet.put(nameNS, namespace);

		return true;
	}

	/**
	 * Aggiunge la definizione delle query di un Dao. Controlla inoltre se
	 * esiste una connessione di default definita per i vari DaoDefinition. In
	 * caso contrario vi mette la connessione di default.
	 * 
	 * @param definition
	 *            definizione DAO
	 * @return true
	 */
	public boolean addDao(SqlMapper definition) {
		String nomeDao = definition.getName().toUpperCase();
		definition.setName(nomeDao);

		// prendiamo la connessione di default
		String connectionName = definition.getDefaultConnectionName();

		if (StringUtility.nvl(connectionName).length() > 0) {
			definition.setDefaultConnectionName(connectionName);
		} else {
			definition.setDefaultConnectionName(defaultConnectionName);
		}

		sqlMapperSet.put(nomeDao, definition);

		return true;
	}

	/**
	 * set delle definizion di dao
	 */
	private Map<String, SqlMapper> sqlMapperSet;

	/**
	 * Getter dell'attributo daoSet.
	 * 
	 * @return the daoSet
	 */
	public Map<String, SqlMapper> getSqlMapperSet() {
		return sqlMapperSet;
	}

	/**
	 * Setter dell'attributo daoSet. Non modifica la connessione di default
	 * 
	 * @param daoSet
	 *            the daoSet to set
	 */
	public void setSqlMapperSet(Map<String, SqlMapper> daoSet) {
		this.sqlMapperSet = daoSet;
	}

	/**
	 * Nome del profilo.
	 */
	protected String name;

	/**
	 * Connection pool usato di default per la connessione.
	 */
	protected String defaultConnectionName;

	/**
	 * Elenco delle sorgenti che definiscono il profilo
	 */
	protected ArrayList<Source> daoSource;

	/**
	 * Elenco dei namespace.
	 */
	protected Map<String, Namespace> daoNamespaceSet;

	/**
	 * Costruttore. Inizializza i set di dao e di namespace creando anche gli
	 * elementi di default.
	 */
	public Profile() {
		name = "default";

		// impostiamo il connection pool di default
		defaultConnectionName = ConnectionPoolManager.getInstance()
				.getDefaultConnectionName();
		daoSource = new ArrayList<Source>();
		sqlMapperSet = new CaseInsensitiveHashMap<SqlMapper>();

		daoNamespaceSet = new CaseInsensitiveHashMap<Namespace>();
		Namespace dns = new Namespace();
		dns.setName("default");
		daoNamespaceSet.put(dns.getName(), dns);
		
		stackTraceDiagnosticHandler = new DefaultStackTraceDiagnosticHandler();
		parameterConverter = new DefaultParameterConverter();
		sQLExceptionTranslator=new DefaultSQLExceptionTranslatorImpl();
	}
	
	/**
	 * Getter dell'attributo parameterConverter
	 * 
	 * @return the parameterConverter
	 */
	public ParameterConverter getParameterConverter() {
		return parameterConverter;
	}

	/**
	 * Setter dell'attributo parameterConverter.
	 * 
	 * @param value
	 *            the parameterConverter to set
	 */
	public void setParameterConverter(ParameterConverter value) {
		this.parameterConverter = value;
	}

	/**
	 * Getter dell'attributo daoSource.
	 * 
	 * @return the daoSource
	 */
	public ArrayList<Source> getDaoSource() {
		return daoSource;
	}

	/**
	 * Setter dell'attributo daoSource
	 * 
	 * @param daoSource
	 *            the daoSource to set
	 */
	public void setDaoSource(ArrayList<Source> daoSource) {
		this.daoSource = daoSource;
	}

	/**
	 * Getter dell'attributo name
	 * 
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**
	 * Setter dell'attributo name
	 * 
	 * @param name
	 *            the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**
	 * Getter dell'attributo defaultConnectionName
	 * 
	 * @return the defaultConnectionName
	 */
	public String getDefaultConnectionName() {
		return defaultConnectionName;
	}

	/**
	 * Setter dell'attributo defaultConnectionName
	 * 
	 * @param defaultConnectionName
	 *            the defaultConnectionName to set
	 */
	public void setDefaultConnectionName(String defaultConnectionName) {
		this.defaultConnectionName = defaultConnectionName;
	}
}
